package com.hbisdt.cet.sample.service.impl;

import com.hbisdt.cet.sample.entity.ResponseData;
import com.hbisdt.cet.sample.entity.dto.CarbonArticleRequest;
import com.hbisdt.cet.sample.entity.po.CarbonArticle;
import com.hbisdt.cet.sample.mapper.CarbonArticleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 碳业务文章缓存服务-基于API的
 *
 * @author : 教学示例
 * @version : 1.0
 * @date : 2025-4-9 11:54
 */
@Service
public class APICarbonArticleService {

    /**
     * 缓存键前缀，与基于注解的进行区分
     */
    public static final String CACHE_KEY_PRIFIX = "API_";

    @Autowired
    private CarbonArticleMapper carbonArticleMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加碳文章
     * 该方法接收一个CarbonArticleRequest对象作为参数，将其转换为CarbonArticle实体并保存到数据库中。
     * 同时，将文章信息缓存到Redis中，以便后续快速访问。
     * @param request 包含文章标题、描述、内容等信息的请求对象
     * @return 返回保存后的CarbonArticle实体对象
     */
    public CarbonArticle addCarbonArticle(CarbonArticleRequest request) {
        // 将请求数据转换为CarbonArticle实体并设置默认值
        CarbonArticle article = new CarbonArticle();
        article.setTitle(request.getTitle());
        article.setDescription(request.getDescription());
        article.setContent(request.getContent());
        article.setPublish(true);
        article.setDelFlag(false);
        // 将文章信息保存到数据库
        carbonArticleMapper.insert(article);
        // 将文章信息缓存到Redis中，使用"API_+文章ID"作为缓存键
        redisTemplate.opsForValue().set(CACHE_KEY_PRIFIX + article.getArticleId(), article);
        return article;
    }

    /**
     * 编辑碳文章信息。
     * 根据请求中的文章ID查找对应的碳文章，更新其标题、描述、内容以及更新时间，
     * 并将更新后的文章信息保存到数据库中。同时，更新Redis缓存中对应的文章信息。
     * @param request 包含文章ID、标题、描述和内容的请求对象
     * @return 更新后的碳文章对象
     */
    public CarbonArticle editCarbonArticle(CarbonArticleRequest request) {
        CarbonArticle article = carbonArticleMapper.selectById(request.getArticleId());
        article.setTitle(request.getTitle());
        article.setDescription(request.getDescription());
        article.setContent(request.getContent());
        article.setUpdateTime(new Date());
        // 将更新后的文章信息保存到数据库
        carbonArticleMapper.updateById(article);
        // 更新Redis缓存中对应的文章信息
        redisTemplate.opsForValue().set(CACHE_KEY_PRIFIX + request.getArticleId(), article);
        return article;
    }

    /**
     * 删除碳文章信息
     * 先删除数据库中的记录，然后删除Redis缓存中的记录
     * @param request
     * @return
     */
    public ResponseData<?> deleteCarbonArticle(CarbonArticleRequest request) {
        carbonArticleMapper.deleteById(request.getArticleId());
        //删除Redis缓存中对应的文章信息
        redisTemplate.delete(CACHE_KEY_PRIFIX + request.getArticleId());
        return ResponseData.ok();
    }

    /**
     * 碳业务文章列表
     * @return java.util.List<com.hbisdt.cet.sample.entity.po.CarbonArticle>
     * @author : 教学示例
     */
    public List<CarbonArticle> getCarbonArticleList() {
        return carbonArticleMapper.selectAll(null);
    }

    /**
     * 根据文章ID获取文章信息。
     * 该方法首先尝试从Redis缓存中获取文章信息，如果缓存中不存在，则从数据库中查询。
     * 如果数据库中也不存在该文章，则返回null，并在控制台输出提示信息。
     * 如果从数据库中查询到文章信息，则返回查询到的文章信息，并将查询到的结果进行缓存。
     * @param articleId 文章的唯一标识符，类型为Long。
     * @return 返回一个CarbonArticle对象，表示查询到的文章信息。如果文章不存在，则返回null。
     */
    public CarbonArticle getById(Long articleId) {
        // 尝试从Redis缓存中获取文章信息
        CarbonArticle article = (CarbonArticle) redisTemplate.opsForValue()
                .get(CACHE_KEY_PRIFIX + articleId);
        // 如果缓存中不存在文章信息，则从数据库中查询
        if (article == null) {
            article = carbonArticleMapper.selectById(articleId);
            // 如果数据库中也不存在该文章，则输出提示信息并返回null
            if (article == null) {
                System.out.println("数据不存在");
                return null;
            }
            // 将查询到的文章信息存入Redis缓存
            redisTemplate.opsForValue().set(CACHE_KEY_PRIFIX + articleId, article);
        }
        //如果缓存中存在，则直接返回缓存数据
        return article;
    }
}
